//
//  QSDropdownMenuView.swift
//  TestSwift
//
//  Created by Song on 2019/8/15.
//  Copyright © 2019 Song. All rights reserved.
//

import UIKit

@objc protocol QSDropdownMenuViewDelegate {
    /// 下拉菜单即将显示
    ///
    /// - Parameter triggerView: 触发显示的视图
    @objc optional func qs_dropdownMenuViewWillShow(dropdownMenuView: QSDropdownMenuView, triggerView: UIView)
    
    /// 下拉菜单即将隐藏
    ///
    /// - Parameter triggerView: 触发显示的视图
    @objc optional func qs_dropdownMenuViewWillHidden(dropdownMenuView: QSDropdownMenuView, triggerView: UIView)
    
    /// 选中那个item
    func qs_didSelectedItem(dropdownMenuView: QSDropdownMenuView, index: Int)
}

class QSDropdownMenuView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        qs_setupSubViews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Func
    private func qs_setupSubViews() {
        backgroundColor = UIColor.init(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5)
        alpha = 0.0
        
        self.addSubview(tableView)
        tableView.snp.makeConstraints { (make) in
            make.left.equalTo(0.0)
            make.top.equalTo(0.0)
            make.width.equalTo(0.0)
            make.height.equalTo(0.0)
        }
        
        // 点击手势
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.tapGest))
        self.addGestureRecognizer(tap)
        tap.delegate = self
    }
    
    @objc private func tapGest() {
        self.hideDropdownMenuView()
    }
    
    /// 显示下拉列表
    ///
    /// - Parameters:
    ///   - triggerView: 触发显示的视图
    ///   - frame: nil：下拉菜单在triggerView下方显示，且宽度与triggerView相同，不为nil：根据该frame显示，只是高度不受这个frame限制，这个frame必须是相对keyWindow的frame
    func showDropdownMenuView(triggerView: UIView, frame: CGRect? = nil) {
        self.triggerView = triggerView
        // 执行代理方法
        if let _ = qs_delegate?.qs_dropdownMenuViewWillShow?(dropdownMenuView: self, triggerView: triggerView) {}
        
        let wid = kWindow
        wid?.addSubview(self)
        self.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        if let f = frame {
            dropdownMenuViewFrame = f
            tableView.snp.updateConstraints({ (make) in
                make.left.equalTo(f.origin.x)
                make.top.equalTo(f.origin.y)
                make.width.equalTo(f.size.width)
            })
        } else {
            let triggerViewFrame = triggerView.convert(triggerView.bounds, to: wid)
            dropdownMenuViewFrame = triggerViewFrame
            tableView.snp.updateConstraints({ (make) in
                make.left.equalTo(triggerViewFrame.origin.x)
                make.top.equalTo(triggerViewFrame.origin.y + triggerViewFrame.size.height)
                make.width.equalTo(triggerViewFrame.size.width)
            })
        }
        
        tableView.superview?.layoutIfNeeded()
        UIView.animate(withDuration: 0.35, animations: { [unowned self] in
            self.alpha = 1.0
            
            self.tableView.snp.updateConstraints({ (make) in
                let height = self.cellHeight * Double(self.dataSource.count)
                if (CGFloat(height) + self.dropdownMenuViewFrame.origin.y) >= UIScreen.main.bounds.height {
                    let h = UIScreen.main.bounds.height - self.dropdownMenuViewFrame.origin.y - 40.0
                    make.height.equalTo(h)
                } else {
                    make.height.equalTo(self.cellHeight * Double(self.dataSource.count))
                }
            })
            
            self.tableView.superview?.layoutIfNeeded()
        })
    }
    
    /// 隐藏
    func hideDropdownMenuView() {
        // 执行代理方法
        if let _ = qs_delegate?.qs_dropdownMenuViewWillHidden?(dropdownMenuView: self, triggerView: triggerView) {}
        
        tableView.superview?.layoutIfNeeded()
        UIView.animate(withDuration: 0.35, animations: { [weak self] in
            self?.alpha = 0.0
            self?.tableView.snp.updateConstraints({ (make) in
                make.height.equalTo(0.0)
            })
            self?.tableView.superview?.layoutIfNeeded()
        }) { (complete) in
            self.removeFromSuperview()
        }
    }
    
    // MARK: - Property
    private var triggerView: UIView!
    private var dropdownMenuViewFrame: CGRect!
    
    var dataSource: Array<String> = []
    weak var qs_delegate: QSDropdownMenuViewDelegate?
    
    var cellHeight = 40.0
    
    var maskViewColor: UIColor = .clear {
        didSet {
            self.backgroundColor = maskViewColor
        }
    }
    
    var contentViewColor: UIColor = .white {
        didSet {
            tableView.backgroundColor = contentViewColor
        }
    }
    
    var titleLeftMargin = 10.0
    var titleRightMargin = 10.0
    var titleAlignment: NSTextAlignment = .left
    var titleFont = UIFont.systemFont(ofSize: 14.0)
    var titleColor = UIColor.black
    
    var lineLeftMargin = 0.0
    var lineRightMargin = 0.0
    var lineColor = UIColor.lightGray
    var hideLastLineColor: Bool = false
    
    // 选中哪个item
    var selectedIndex: Int = 0
    
    // MARK: - Widget
    private lazy var tableView: UIView = {
        let view = UITableView.init(frame: .zero, style: .plain)
        
        view.separatorStyle = .none
        view.showsVerticalScrollIndicator = false
        view.showsHorizontalScrollIndicator = false
        
        view.dataSource = self
        view.delegate = self
        
        if #available(iOS 11.0, *) {
            view.contentInsetAdjustmentBehavior = .never
        }
        
        // 注册
        view.register(QSDropdownMenuCell.self, forCellReuseIdentifier: "QSDropdownMenuCell")
        
        return view
    }()
}

extension QSDropdownMenuView: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "QSDropdownMenuCell") as! QSDropdownMenuCell
        cell.selectionStyle = .none
        
        cell.contentView.backgroundColor = contentViewColor
        
        let title = dataSource[indexPath.row]
        cell.title = title
        cell.titleLeftMargin = titleLeftMargin
        cell.titleRightMargin = titleRightMargin
        cell.titleAlignment = titleAlignment
        cell.titleFont = titleFont
        cell.titleColor = titleColor
        
        cell.lineLeftMargin = lineLeftMargin
        cell.lineRightMargin = lineRightMargin
        cell.lineColor = lineColor
        
        cell.isChoose = selectedIndex == indexPath.row
        
        if hideLastLineColor {
            cell.hideLineColor = indexPath.row == (dataSource.count - 1)
        } else {
            cell.hideLineColor = false
        }
        
        return cell
    }
}

extension QSDropdownMenuView: UITableViewDelegate {
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return UIView.init()
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 0.01
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView.init()
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0.01
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return CGFloat(cellHeight)
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if selectedIndex == indexPath.row {
            return
        }
        
        // 执行代理方法
        if let _ = qs_delegate?.qs_didSelectedItem(dropdownMenuView: self, index: indexPath.row) {}
        self.hideDropdownMenuView()
    }
}

extension QSDropdownMenuView: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if (touch.view?.isDescendant(of: self.tableView))! {
            return false
        }
        return true
    }
}


class QSDropdownMenuCell: UITableViewCell {
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        qs_setupSubViews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - func
    private func qs_setupSubViews() {
        contentView.addSubview(titleLab)
        titleLab.snp.makeConstraints { (make) in
            make.left.equalTo(10.0)
            make.right.equalTo(-10.0)
            make.centerY.equalToSuperview()
        }
        
        contentView.addSubview(lineView)
        lineView.snp.makeConstraints { (make) in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(1.0)
        }
    }
    
    // MARK: - Property
    var titleLeftMargin = 10.0 {
        didSet {
            titleLab.snp.updateConstraints { (make) in
                make.left.equalTo(abs(titleLeftMargin))
            }
        }
    }
    var titleRightMargin = 10.0 {
        didSet {
            titleLab.snp.updateConstraints { (make) in
                make.right.equalTo(-abs(titleRightMargin))
            }
        }
    }
    var titleAlignment: NSTextAlignment = .left {
        didSet {
            titleLab.textAlignment = titleAlignment
        }
    }
    var titleFont = UIFont.systemFont(ofSize: 14.0) {
        didSet {
            titleLab.font = titleFont
        }
    }
    var titleColor = UIColor.black {
        didSet {
            titleLab.textColor = titleColor
        }
    }
    var selectedTitleColor = UIColor.blue
    var title: String = "" {
        didSet {
            titleLab.text = title
        }
    }
    
    var lineLeftMargin = 0.0 {
        didSet {
            lineView.snp.updateConstraints { (make) in
                make.left.equalTo(abs(lineLeftMargin))
            }
        }
    }
    var lineRightMargin = 0.0 {
        didSet {
            lineView.snp.updateConstraints { (make) in
                make.right.equalTo(-abs(lineRightMargin))
            }
        }
    }
    var lineColor = UIColor.lightGray {
        didSet {
            lineView.backgroundColor = lineColor
        }
    }
    var hideLineColor: Bool = false {
        didSet {
            lineView.isHidden = hideLineColor
        }
    }
    
    var isChoose: Bool = false {
        didSet {
            if isChoose {
                titleLab.textColor = selectedTitleColor
            } else {
                titleLab.textColor = titleColor
            }
        }
    }
    
    // MARK: - Widget
    private lazy var titleLab: UILabel = {
        let lab = UILabel.init()
        lab.textColor = .black
        lab.font = UIFont.systemFont(ofSize: 14.0)
        lab.textAlignment = .left
        return lab
    }()
    
    private lazy var lineView: UIView = {
        let view = UIView.init()
        view.backgroundColor = .lightGray
        return view
    }()
}
